package com.example.cnotebook;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.media.MediaPlayer;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.Toast;

import com.example.cnotebook.adapter.AudioListViewAdapter;
import com.example.cnotebook.pojo.AudioInfo;
import com.example.cnotebook.util.OKHttpUtil;
import com.example.cnotebook.util.PutAudioToAI;
import com.example.cnotebook.util.UserConstant;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Enumeration;

public class ESPActivity extends AppCompatActivity implements View.OnClickListener, OKHttpUtil.CallBack {

    private ListView listView;
    private File filesDir;//持久文件目录
    private String esp32Ip;
    private ArrayList<AudioInfo> audioInfos = new ArrayList<>();
    private ProgressBar progressBar;
    private Button putData;
    private Button getDate;
    private DatagramSocket socket;

    private AudioListViewAdapter audioListViewAdapter;
    private SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日");

    private volatile boolean b = true;
    private volatile String command = "";
    private int esp32FileNumber = 0;

    private Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(@NonNull Message msg) {
            if (msg.what == 0x1) {
                getDate.setEnabled(false);
                putData.setEnabled(false);
                progressBar.setVisibility(View.VISIBLE);
            } else if (msg.what == 0x2) {
                getDate.setEnabled(true);
                putData.setEnabled(true);
                progressBar.setVisibility(View.GONE);
                Toast.makeText(ESPActivity.this, "暂无录音文件", Toast.LENGTH_SHORT).show();
            } else {
                getDate.setEnabled(true);
                putData.setEnabled(true);
                audioListViewAdapter.notifyDataSetChanged();
                progressBar.setVisibility(View.GONE);
            }
            return false;
        }
    });

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_e_s_p);
        findViewById(R.id.iv_back).setOnClickListener(this);
        getDate = findViewById(R.id.getData);
        getDate.setOnClickListener(this);
        putData = findViewById(R.id.putData);
        putData.setOnClickListener(this);
        progressBar = findViewById(R.id.progressBar);
        listView = findViewById(R.id.listview);
        filesDir = getFilesDir();
        //FilesDir：/data/user/0/com.scc.datastorage/files
        Log.e("File", "FilesDir：" + filesDir.getAbsolutePath());
//        File cacheDir = getCacheDir();//缓存文件目录
        //CacheDir：/data/user/0/com.scc.datastorage/cache
//        Log.e("File", "CacheDir：" + cacheDir.getAbsolutePath());
        audioListViewAdapter = new AudioListViewAdapter(audioInfos, this);
        listView.setAdapter(audioListViewAdapter);
        try {
            getLocalAudio();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void getLocalAudio() throws IOException {
        audioInfos.clear();
        System.out.println(filesDir);
        File[] files = filesDir.listFiles();
        if (files == null) return;
        for (File file : files) {
            String fileName = file.getName();
            if (!fileName.contains("n")) {
                continue;
            }
            String[] ns = file.getName().split("n");
            AudioInfo audioInfo = new AudioInfo();
            audioInfo.setPlay(false);
            MediaPlayer mediaPlayer = new MediaPlayer();
            mediaPlayer.setDataSource(file.getPath());
            audioInfo.setMediaPlayer(mediaPlayer);
            audioInfo.setFilePath(file.getPath());
            audioInfo.setCreateDate(format.format(Long.parseLong(ns[0])));
            audioInfos.add(audioInfo);
        }
        System.out.println("audioInfos:" + audioInfos);
        System.out.println("audioInfos:" + audioInfos.size());
        audioListViewAdapter.notifyDataSetChanged();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.iv_back:
                finish();
                break;
            case R.id.getData:
//                if (!checkWifi()) {
//                    Toast.makeText(this, "请先连接设备wifi", Toast.LENGTH_LONG).show();
//                    return;
//                }

                new Thread() {
                    @Override
                    public void run() {
                        try {
                            handler.sendEmptyMessage(0x1);
                            getESP32IP();
                            if (audioInfos.size() == 0) {
                                handler.sendEmptyMessage(0x2);
                                return;
                            }
                            getAudioData();
                        } catch (IOException | InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }.start();
                break;
            case R.id.putData:
                new Thread() {
                    @Override
                    public void run() {
                        putAudio();
                    }
                }.start();
                break;
        }
        System.out.println(getLocalIpAddress());
    }

    /**
     * 判断当前连接的WiFi是不是ESP32开启的
     */
    private boolean checkWifi() {
        WifiManager wifiManager = (WifiManager) this.getSystemService(WIFI_SERVICE);
        if (wifiManager == null) {
            return false;
        }
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        System.out.println(wifiInfo.toString());
        System.out.println("wifi名称为：" + wifiInfo.getSSID());
        if (wifiInfo.getSSID().equals("ESP-AP")) return true;

//        WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
//        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        System.out.println(wifiInfo.getSSID().replace("\"", "").replace("<", "").replace(">", ""));
        return false;
    }

    private void putAudio() {
        final ArrayList<File> files = new ArrayList<>();
        //筛选没有上传的音频
        for (AudioInfo audioInfo : audioInfos) {
            String filePath = audioInfo.getFilePath();
            String s = filePath.split(".wav")[0];
            String substring = s.substring(s.length() - 1);
            if (substring.equals("n")) {
                File file = new File(filePath);
                files.add(file);
            }
        }
        if (files.size() == 0) {
            Toast.makeText(this, "没有待上传的文件", Toast.LENGTH_LONG).show();
            return;
        }
        OKHttpUtil.uploadFile("/note/uploadAudio/" + UserConstant.userInfo.getId(), files, new OKHttpUtil.CallBack() {
            @Override
            public void onSuccess(JSONObject response) throws JSONException {
                for (File file : files) {
                    String name = file.getName();
                    System.out.println("name：" + name);
                    String oldPath = filesDir + "/" + name;
                    String newName = name.replace("n", "y");
                    String newPath = oldPath.replace(name, newName);
                    boolean b = file.renameTo(new File(newPath));
                    System.out.println(b);
                }
                audioInfos.clear();
                audioListViewAdapter.notifyDataSetChanged();
                Toast.makeText(ESPActivity.this, "添加成功！", Toast.LENGTH_SHORT).show();
                UserConstant.homeIsSaveData = true;
                UserConstant.userIsSaveData = true;
            }

            @Override
            public void onFailure(int errorNo, String strMsg) {

            }
        }, this);
    }

    /**
     * 交换ESP32和手机的IP地址，并获取ESP32发送的文件信息
     *
     * @throws IOException
     */
    private void getESP32IP() throws IOException {
        DatagramSocket socket = new DatagramSocket();
        InetAddress address = InetAddress.getByName("255.255.255.255");
        SocketAddress socketAddress = new InetSocketAddress(address, 7788);
        byte[] bytes = getLocalIpAddress().getBytes();
        DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, socketAddress);
        //发送UDP广播，数据为手机的IP
        socket.send(datagramPacket);
        socket.disconnect();
        socket.close();
        receiveESPIp();
    }

    private void receiveESPIp() throws IOException {
        byte[] bytes;
        socket = new DatagramSocket(10130);
        bytes = new byte[1024];
        DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
        System.out.println("等待接收IP与所有音频基本信息");
        socket.receive(datagramPacket);
        esp32Ip = new String(datagramPacket.getData(), 0, datagramPacket.getLength(), StandardCharsets.UTF_8);
        System.out.println("esp32IP========" + esp32Ip);
        //xxx@xxx@ip
        String[] split = esp32Ip.split("@");
        esp32FileNumber = Integer.parseInt(split[0]);
        if (split.length > 1) {
            for (int i = 0; i < esp32FileNumber; i++) {
                AudioInfo audioInfo = new AudioInfo();
                audioInfos.add(audioInfo);
            }
        }
        socket.close();
    }

    /**
     * 获取ESP32发送的音频文件
     *
     * @throws IOException
     */
    private void getAudioData() throws IOException, InterruptedException {
        ServerSocket serverSocket = new ServerSocket(8089);
        System.out.println("文件数量为：" + esp32FileNumber);
        command = "SEND";
        while (esp32FileNumber > 0) {
            System.out.println("等待客户端连接...");
            Socket socket = serverSocket.accept();
            System.out.println("有新的连接...");
            //SEND指令，对应ESP32发送音频文件的指令
            if (command.equals("SEND")) {
                OutputStream os = socket.getOutputStream();
                os.write("SEND".getBytes());
                os.close();
                socket.close();
                //SENDED表示发送完成，APP开始接收音频文件
                command = "SENDED";
                System.out.println("完成指令发送");
                continue;
            }
            if (command.equals("SENDED")) {
                System.out.println("开始接收文件...");
                esp32FileNumber--;
                InputStream is = socket.getInputStream();
                System.out.println("文件大小为：" + is.available());
//                if (is.available() != 0) {
                //n.wav表示文件未上传到服务器y.wav为已上传
                long l = System.currentTimeMillis();
                String s = filesDir + "/" + l + "n.wav";
                AudioInfo audioInfo = audioInfos.get(audioInfos.size() - esp32FileNumber - 1);
                audioInfo.setFilePath(s);
                audioInfo.setCreateDate(format.format(l));
                FileOutputStream fos = new FileOutputStream(s);
                byte[] a = new byte[2048];
                int len = 0;
                while ((len = is.read(a)) != -1) {
                    fos.write(a, 0, len);
                }
                fos.close();
                MediaPlayer mediaPlayer = new MediaPlayer();
                mediaPlayer.setDataSource(s);
                audioInfo.setMediaPlayer(mediaPlayer);
//                    audioInfo.setDuration(audioInfo.getDuration());
//                }
                is.close();
            }
            socket.close();
            System.out.println("文件剩余：" + esp32FileNumber);
        }
        handler.sendEmptyMessage(0x3);
    }

    public String getLocalIpAddress() {
        try {
            Enumeration<NetworkInterface> en = NetworkInterface
                    .getNetworkInterfaces();
            while (en.hasMoreElements()) {
                NetworkInterface ni = en.nextElement();
                Enumeration<InetAddress> enIp = ni.getInetAddresses();
                while (enIp.hasMoreElements()) {
                    InetAddress inet = enIp.nextElement();
                    if (!inet.isLoopbackAddress()
                            && (inet instanceof Inet4Address)) {
                        return inet.getHostAddress().toString();
                    }
                }
            }
        } catch (SocketException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return null;
    }


    @Override
    public void onSuccess(JSONObject response) throws JSONException {
        Toast.makeText(this, "添加成功！", Toast.LENGTH_SHORT).show();
        UserConstant.homeIsSaveData = true;
        UserConstant.userIsSaveData = true;
    }

    @Override
    public void onFailure(int errorNo, String strMsg) {

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (socket != null) {
            socket.close();
        }
    }
}
